package com.fast.alden.admin.service.impl;

import com.fast.alden.admin.entity.dto.ReadMessagesParam;
import com.fast.alden.admin.service.MessageCenterService;
import com.fast.alden.admin.service.SysMessageService;
import com.fast.alden.admin.util.SecurityUtils;
import com.fast.alden.admin.web.websocket.MessageCountWebSocketServer;
import com.fast.alden.data.model.SysMessage;
import com.fast.alden.data.model.SysUser;
import com.fast.alden.data.repo.SysMessageRepository;
import jakarta.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class MessageCenterServiceImpl implements MessageCenterService {
    @Resource
    private SysMessageService messageService;
    @Resource
    private SysMessageRepository messageRepository;
    @Resource
    private MessageCountWebSocketServer messageCountWebSocketServer;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public Page<SysMessage> messagePage(SysMessage searchVo, Pageable pageable) {
        SysUser current = SecurityUtils.getCurrentUser();
        searchVo.setReceiverId(current.getId());
        return messageService.search(searchVo, pageable);
    }

    @Override
    public SysMessage retrieveMessage(Long msgId) {
        SysUser current = SecurityUtils.getCurrentUser();
        SysMessage message = messageService.retrieveWithException(msgId);
        // 接收人不是当前用户
        if (!message.getReceiverId().equals(current.getId())) {
            return null;
        }
        return message;
    }

    @Override
    public void readMessages(ReadMessagesParam param) {
        SysUser current = SecurityUtils.getCurrentUser();
        List<SysMessage> messages;
        if (param.getAll()) {
            SysMessage searchVo = new SysMessage();
            searchVo.setReceiverId(current.getId());
            messages = messageService.search(searchVo);
        } else {
            messages = messageService.list(param.getIds()).stream().filter(msg -> msg.getReceiverId().equals(current.getId())).toList();
        }
        messages.forEach(msg -> {
            msg.setReadState(true);
            msg.setReadTime(LocalDateTime.now());
        });
        messageService.updateAll(messages);
        refreshWebSocket();
    }

    @Override
    public Long countUnreadMessage(Long receiverId) {
        return messageRepository.countByReceiverIdIsAndReadStateIsFalse(receiverId);
    }

    @Override
    public void sendMessage(List<SysMessage> messages) {
        messages = messageRepository.saveAll(messages);

        refreshWebSocket();
    }

    private void refreshWebSocket() {
        threadPoolTaskExecutor.execute(() -> {
            messageCountWebSocketServer.refreshCount();
        });
    }
}
